package com.sunda.spmsweb.util;

import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.DecodedJWT;
import org.apache.shiro.authc.AuthenticationException;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * @program: spms
 * @author: Wayne Wu
 * @description: JWT 工具类
 * @create: 2020-10-26 15:32
 */
public class JWTUtil {
    // 过期时间 24 小时
    private static final long EXPIRE_TIME = 7 * 24 * 60 * 60 * 1000;
    // 密钥
    private static final String SECRET = "SUNDA+SHIRO+JWT";

    public static String createOaToken(String userId) {
        try {
            Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            // 附带username信息
            return JWT.create()
                    .withClaim("userId", userId)
                    //到期时间
                    .withExpiresAt(date)
                    //创建一个新的JWT，并使用给定的算法进行标记
                    .sign(algorithm);
//        } catch (UnsupportedEncodingException e) {
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 生成 token, 5min后过期
     *
     * @param username 用户名
     * @return 加密的token
     */
    public static String createToken(String username, String role) {
        try {
            Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            // 附带username信息
            return JWT.create()
                    .withClaim("userId", username)
                    .withClaim("role", role)
                    //到期时间
                    .withExpiresAt(date)
                    //创建一个新的JWT，并使用给定的算法进行标记
                    .sign(algorithm);
//        } catch (UnsupportedEncodingException e) {
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 校验 token 是否正确
     *
     * @param token    密钥
     * @param userId 用户编号
     * @return 是否正确
     */
    public static boolean verify(String token, String userId) {
        try {
            Algorithm algorithm = Algorithm.HMAC256(SECRET);
            //在token中附带了username信息
            JWTVerifier verifier = JWT.require(algorithm)
                    .withClaim("userId", userId)
                    .build();
            //验证 token
            verifier.verify(token);
            return true;
        } catch (TokenExpiredException exception) {
            return false;
        } catch (AuthenticationException exception) {
            return false;
        }
    }

    /**
     * 获得token中的信息，无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static String getUserId(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userId").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    /**
     * 获得token中的信息，无需secret解密也能获得
     *
     * @return token中包含的用户名
     */
    public static String getUsername(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("username").asString();
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    public static List<String> getUserRole(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            //返回 role 字符串;
            //return jwt.getClaim("role").asString();
            //返回 role 字符串数组;
            return Arrays.asList(jwt.getClaim("role").asString().split(","));
        } catch (JWTDecodeException e) {
            return null;
        }
    }

    public static void main(String[] args) {
        String token = "eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJyb2xlIjoiYWRtaW4sdGVzdCIsImV4cCI6MTYwMzcxNDgzMiwidXNlcm5hbWUiOiJqYXZhIn0.GkeREDKkkEcaLEnL4VCgPwQtZY2I_hsxITjf7z7gxxw";
        System.out.println("==== " + getUsername(token));
        System.out.println("====" + getUserRole(token));


        Date date = new Date(System.currentTimeMillis() + EXPIRE_TIME);
        Algorithm algorithm = Algorithm.HMAC256(SECRET);
        // 附带username信息
        String oaToken = JWT.create().withExpiresAt(date).sign(algorithm);
        System.out.println("token:" + oaToken);//eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJleHAiOjE2MTc3NTY2NjJ9.Z5DGPyA10VBF1WC77GprP-Llv-O8ySHhmRUGV-h7tU0
    }
}
